package main

import (
	"fmt"
)

/*
	编写学生结构体 实现学生的增删改查 并将结果保存到文件中
*/
//定义学生结构体
type Students struct {
	Id    int      `json:"id"`
	Name  string   `json:"name"`
	Age   int      `json:"age"`
	Class []string `json:"class"`
}

// NewStudent 构造学生结构体的函数
func NewStudent(id int, name string, age int, class []string) *Students {
	return &Students{
		Id:    id,
		Name:  name,
		Age:   age,
		Class: class,
	}
}

// StuMgr 定义一个学生管理者结构体，用来保存学生数据
type StuMgr struct {
	allSts []map[string]*Students //用来保存学生数据
}

// NewStuMgr 构造学生管理器的结构体函数
func NewStuMgr() *StuMgr {
	return &StuMgr{
		allSts: make([]map[string]*Students, 0),
	}
}

// Viewallsts 查看全部学生信息
/*
	因为学生信息都保存在学生管理器的结构体中,想要查看学生信息需要一个接收者,这个接收者s *StuMgr返回的是一个经过make初始化的存储空间
	因为是一个key为string类型、value为*Student的切片类型,因此查看学生信息可以通过 切片类型的for循环拿到对应的value，这个value就是map类型
然后这个循环这个value,打印出values为*Student保存的值
*/
func (s *StuMgr) Viewallsts() {
	fmt.Println("查看全部学生信息")
	//从s.allSts中把数据拿出来并打印
	for _, value := range s.allSts {
		for _, values := range value {
			fmt.Println(values.Id, values.Name, values.Age, values.Class)
		}
	}
}

// Viewoncests 查看单个学生信息
/*
	因为学生信息都保存在学生管理器的结构体中,想要查看学生信息需要一个接收者,这个接收者s *StuMgr返回的是一个经过make初始化的存储空间
该函数接收一个传递进来的int参数,通过输入的id与值为*Student类型中的id对比,如果相等,则打印出这个id对应的用户信息
	接收者表示的是调用该方法的具体类型变量
*/
func (s *StuMgr) Viewoncests(id int) bool {
	fmt.Println("查看单个学生信息")
	for _, value := range s.allSts {
		//fmt.Println(value)
		for _, values := range value {
			//fmt.Println(values)
			if values.Id == id {
				fmt.Println(values.Id, values.Name, values.Age, values.Class)
				return true
			}
		}
	}
	return false
}

// AddMsgsts  增加学生信息
/*
	该函数接收一个*Students类型的参数 最后把增加的信息通过接收者s *StuMgr 保存到StuMgr结构体中
先是循环切片,拿个每个索引对应的值，该值是map类型。然后在通过map的ok判断方法，检查存储空间中是否有已经存在的键所对应的值，如果有则直接eturn false
如果存储空间中没有，则使用make初始化一个map类型，将传进来的形参保存到这个map类型中,再将这个map通过切片的append方法追加到存储空间中,实现增加功能
*/
func (s *StuMgr) AddMsgsts(student *Students) bool {
	fmt.Println("增加学生信息")
	for _, value := range s.allSts {
		if _, ok := value[student.Name]; ok {
			return false
		}
	}
	stsmsg := make(map[string]*Students)
	stsmsg[student.Name] = student
	s.allSts = append(s.allSts, stsmsg)
	return true
}

// UpdateMsgsts 更新函数
/*
	通过传递的形参id,判断想要更新的信息是否存在,先是循环切片，拿到map 再通过循环map，进行传入的id与保存的id进行对比，如果相等,则调用另一个形参student
进行map类型的增加操作，将旧值修改为新值
*/
func (s *StuMgr) UpdateMsgsts(id int, student *Students) bool {
	fmt.Println("更新学生信息")
	for _, values := range s.allSts {
		for _, value := range values {
			if value.Id == id {
				value.Id = student.Id
				value.Name = student.Name
				value.Age = student.Age
				value.Class = student.Class
				return true
			}
		}
	}
	return false
}

// DelMsgsts 删除学生信息
/*
	通过传入的形参id判断对应的信息是否存在，先进行切片循环,拿到对应的map 在进行map循环操作,判断*Student值中是否有与形参id一样的值，如果有，则进行
删除map操作，删除后,再进行判断map的长度是否为0了，如果确实是0，则进行切片的删除操作，将切片中的索引进行删除即可
*/
func (s *StuMgr) DelMsgsts(id int) bool {
	fmt.Println("删除学生信息")
	for index, value := range s.allSts {
		for key, values := range value {
			if values.Id == id {
				delete(value, key)
				if len(value) == 0 {
					s.allSts = append(s.allSts[:index], s.allSts[index+1:]...)
				}
				return true
			}
		}
	}
	return false
}
